#ifndef __INCLUDED_EVEREST_BASEDEF_H
#define __INCLUDED_EVEREST_BASEDEF_H


#define BEGIN_NAMESPACE_EVEREST namespace everest {
#define END_NAMESPACE_EVEREST }
#define NS_EVEREST  everest


#define EVEREST_UNCOPIABLE(cls) \
	private: \
		cls(const cls& ); \
		cls& operator=(const cls&);

#define EVEREST_INTERFACE(intf) virtual ~intf() {}

#define EVEREST_ERRSRC_ARGS  __FILE__, __LINE__


#include <string>
#include <vector>
#include <list>

#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include <stdio.h>

BEGIN_NAMESPACE_EVEREST

	typedef std::string         String;
	typedef std::vector<String> StringVector;
	typedef std::vector<int>    IntVector;
	typedef std::vector<char>   ByteVector;
	typedef struct timeval      Timestamp;
	typedef struct tm           DateTime;

	template<typename CLS>
	class CommonPtr
	{
	private:
		explicit CommonPtr(const CommonPtr<CLS>&);
		CommonPtr<CLS>& operator=(const CommonPtr<CLS>&){}

	public:
		typedef CLS ClassType;

	public:
		CommonPtr() : m_ptr(NULL){}
		CommonPtr(ClassType *ptr) : m_ptr(ptr){}

		CommonPtr<CLS>& operator=(ClassType *ptr)
		{
			if ( m_ptr ) this->release();
			m_ptr = ptr;
			return *this;
		}

		ClassType * operator->() { return m_ptr; }
		const ClassType * operator->() const { return m_ptr; }

		ClassType& operator*() { return *m_ptr;}
		const ClassType& operator*() const { return *m_ptr;}

		bool operator==(const CommonPtr<CLS>& ptr) { return m_ptr == ptr.m_ptr; }
		bool operator==(const ClassType *ptr) { return m_ptr == ptr; }

		void release ()
		{
			if (m_ptr != NULL) delete m_ptr;
			m_ptr = NULL;
		}

		void reset()
		{
			m_ptr = NULL;
		}

		const ClassType * ptr() const { return m_ptr;}
		ClassType * ptr() { return m_ptr; }

		const ClassType& ref() const { return *m_ptr;}
		ClassType& ref() { return *m_ptr;}

		bool isNull() const { return m_ptr == NULL; }

		ClassType * detach() {
			ClassType * p = m_ptr;
			m_ptr = NULL;
			return p;
		}

	protected:
		ClassType *m_ptr;
	};

	inline String TimestampToString(const Timestamp& tm)
	{
		char buf[128];
		struct tm t;
		localtime_r(&tm.tv_sec, &t);
		snprintf(buf, 128, "%04d-%02d-%2d %02d:%02d:%02d.%03d",
				 t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
				 t.tm_hour, t.tm_min, t.tm_sec, (int)(tm.tv_usec / 1000));
		if ( t.tm_isdst ) strcat(buf, "DST");
		return String(buf);
	}

	inline String DateTimeToString(const DateTime& dt)
	{
		char buf[128];
		snprintf(buf, 128, "%04d-%02d-%2d %02d:%02d:%02d.000",
				 dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday,
				 dt.tm_hour, dt.tm_min, dt.tm_sec);
		if ( dt.tm_isdst ) strcat(buf, "DST");
		return String(buf);
	}

END_NAMESPACE_EVEREST


#endif // __INCLUDED_EVEREST_BASEDEF_H
